ident = '$Id: forms.py 104 2006-05-25 22:06:43Z ahmad $'

'''The Form and Survey UI components'''
import sys, wx, rex, common, images, re, base, editors
from xml.sax 	import saxutils
from xml.dom	import minidom

# From referral page to Follow up -> go to referral
CG_LIST = 100
RB_SUBS = 101
RB_LIST = 102
CB_ARCHIVE=103
ID_SEND	=104

class form( base.editor ):
	def __init__( self, account, frm, treeitem ):
		base.editor.__init__( self, account, frm, treeitem )
		#self.header = self.editor.add_page( "Header", EDIT_KIND_HTML, -1 )
		#self.footer = self.editor.add_page( "Footer", EDIT_KIND_HTML, -1 )
		self.load_rex_object()

	def load_rex_object( self ):
		if self.rex_object is None: return
		# Add the standard properties
		cur = wx.BusyCursor()
		try:
			xmlstring = self.rex_object.execute( "get", ID=self.rex_object["id"] )
			self.rex_object.fromxml( xmlstring )
			base.editor.load_rex_object( self )
		except:
			common.show_error( "Failed to load from rex object" )
		del cur
		
class survey( base.editor ):
	def __init__( self, account, sur, treeitem ):
		base.editor.__init__( self, account, sur, treeitem )
		self.load_rex_object()
		self.qorder_dirty = False
		
		#self.email_editor   = sui_email_editor( self )
		#if self.rex_object.module.lower() == "survey":
		#	self.q_editor		= sui_questions_editor( self )
		#	self.c_notifiers	= sui_notifiers_editor( self, 'c' )
		#	self.t_notifiers	= sui_notifiers_editor( self, 't' )
		#if self.rex_object.module.lower() == "Referral":
		#	self.r_notifiers	= sui_notifiers_editor( self, 'r' )

	def load_rex_object( self ):
		if self.rex_object is None: return
		# surveys need to be loaded from rex
		if self.account.window: self.account.window.SetStatusText("Loading page..")
		wx.Yield()
		cur = wx.BusyCursor()
		try:
			xmlstring = self.rex_object.execute( "get2", ID=self.rex_object["id"] )
			self.rex_object.fromxml( xmlstring )
			base.editor.load_rex_object( self )
		except:
			common.show_error( "failed to load the survey" )
		del cur
		# Reposition the splitter
		self.vSplitter.SetSashPosition( self.sash_pos )
		if self.account.window: self.account.window.SetStatusText( "Ready" )

	def SetDirty( self, dirty ):
		if dirty:
			self.set_var_dirty( None )
		
	def OnSave( self, event = None ):
		cur = wx.BusyCursor()
		#try:
		if True:
			# Save any dirty questions
			if self.rex_object.module.lower() == "survey":
				for q in self.questions_editor.questions.values():
					if q.dirty:
						msg = "Saving question id[%s] , please wait..." % q["id"]
						self.account.window.SetStatusText( msg )
						wx.Yield()
						wx.Yield()
						wx.Yield()
						q.save()
						q.dirty = False
				self.questions_editor.delete_cancel_btn.SetLabel("Delete")
				# Save the question ordering
				if self.qorder_dirty:
					self.account.window.SetStatusText( "Saving questions order, please wait..." )
					wx.Yield()
					wx.Yield()
					wx.Yield()
					order = self.questions_editor.GetQOrder()
					self.account.execute( self.rex_object.module, "questions_reorder", DOM=order )
					self.SetDirty( False )
					self.qorder_dirty = False
				# Save any dirty notifiers
				# TEMP
				if False:
					for n in self.notifiers_editor.notifiers.values():
						if n.dirty: 
							msg = "Saving notifier id[%s] , please wait..." % n["id"]
							self.account.window.SetStatusText( msg )
							wx.Yield()
							wx.Yield()
							wx.Yield()
							n.save()
							n.dirty = False
					self.notifiers_editor.delete_cancel_btn.SetLabel("Delete")
					for n in self.notifiers_editor.notifiers.values():
						if n.dirty: 
							msg = "Saving notifier id[%s] , please wait..." % n["id"]
							self.account.window.SetStatusText( msg )
							wx.Yield()
							wx.Yield()
							wx.Yield()
							n.save()
							n.dirty = False
					self.notifiers_editor.delete_cancel_btn.SetLabel("Delete")
				if ( self.rex_object.module.lower() == "referral" ) : #or ( ( self.rex_object.module.lower() == "survey" ) and ( self.rex_object["version"] == "1.0" ) ):
					for n in self.notifiers_editor.notifiers.values():
						if n.dirty: 
							msg = "Saving notifier id[%s] , please wait..." % n["id"]
							self.account.window.SetStatusText( msg )
							wx.Yield()
							wx.Yield()
							wx.Yield()
							n.save()
							n.dirty = False
					self.notifiers_editor.delete_cancel_btn.SetLabel("Delete")
		#except:
		#	wx.MessageBox( "Errors while saving the questions or notifiers." )
		self.account.window.SetStatusText( "Ready" )
		base.editor.OnSave( self )
	
	def SetSavePoints( self ):
		self.header.EmptyUndoBuffer()
		self.footer.EmptyUndoBuffer()
		self.email.EmptyUndoBuffer()
		if self.object_label == "Survey":
			self.front_page.EmptyUndoBuffer()
		if ( self.object_label == "Referral" ) or ( ( self.object_label == "Survey" ) and ( self.rex_object["version"] == "1.0" ) ):
			self.r_front_page.EmptyUndoBuffer()
			self.r_email.EmptyUndoBuffer()
			self.a_front_page.EmptyUndoBuffer()
			self.t_email.EmptyUndoBuffer()
			self.f_email.EmptyUndoBuffer()
		self.thankyou_page.EmptyUndoBuffer()
		
	def OnPublish( self, event ):
		dlg = sender( self, self.account, self.rex_object )
		common.metalic( dlg )
		dlg.Show()

class suiSenderDropTarget( wx.PyDropTarget ):
	def __init__( self, list_object, sui ):
		wx.PyDropTarget.__init__( self )
		self.list 	= list_object
		self.sui	= sui
		self.data   = wx.PyTextDataObject(" ")
		self.SetDataObject( self.data )
		
	def OnEnter( self, x, y, d ):
		return wx.DragCopy
	
	def OnLeave( self ):
		pass
	
	def OnDrop( self, x, y ):
		return self.list.IsEnabled()
	
	def OnDragOver( self, x, y, d ):
		if self.list.IsEnabled():
			return wx.DragCopy
		else:
			return wx.DragNone
	
	def OnData( self, x, y, d ):
		if self.GetData():
			data = self.data.GetText()			
			if data[:6]=="<group":
				# We are adding a group
				obj = group( data, self.sui.account )
			elif data[:8]=="<contact":
				obj = contact( data, self.sui.account )
			else:
				return wx.DragNone
			# Add to the list
			self.sui.AppendObject( obj )
			self.sui.resize_columns()
			return wx.DragCopy
		else:
			common.dprint( "Failed to get the dnd data" )
		return wx.DragNone

class sender( wx.Dialog ):
	def __init__( self, parent, account, sur ):
		title = "Sender - [ %s ] %s" % ( sur["id"], sur["name"] )
		wx.Dialog.__init__( self, parent, -1, title, wx.DefaultPosition, wx.Size( 350, 400 )  )
		self.objects = {}		# List of objects to send to
		self.account = account
		self.survey  = sur
		self.current_id = 0
		sizer = wx.BoxSizer( wx.VERTICAL )
		sizer.Add( wx.StaticText ( self, -1, "Drag and drop contacts to send to:" ), 0, wx.LEFT | wx.RIGHT, 20 )
		self.list = wx.ListCtrl( self, CG_LIST, style=wx.LC_REPORT )
		sizer.Add( self.list, 1, wx.EXPAND | wx.LEFT | wx.RIGHT, 20 )
		info = wx.ListItem()
		info.m_mask = wx.LIST_MASK_TEXT # | wx.LIST_MASK_IMAGE | wx.LIST_MASK_FORMAT
		#info.m_image = -1
		info.m_format = 0
		info.m_text = "[X]ID"
		self.list.InsertColumnInfo(0, info)
		info.m_text = "Name"
		self.list.InsertColumnInfo(1, info)
		info.m_text = "Kind"
		self.list.InsertColumnInfo(2, info)
		info.m_text = "" # One extra
		self.list.InsertColumnInfo(3, info)
		# Set the drop target
		dt = suiSenderDropTarget( self.list, self )
		self.list.SetDropTarget( dt )		
		# Set the drag and drop events
		self.list.Bind( wx.EVT_LIST_BEGIN_DRAG, self.OnBeginDrag )
		self.resize_columns()
		
		# Add the reply and cc address boxes
		asizer = wx.FlexGridSizer( 2, 2, 3, 3 )
		asizer.AddGrowableCol( 1 )
		self.reply_address = wx.TextCtrl( self, -1 ) 
		self.cc_address = wx.TextCtrl( self, -1 )
		asizer.Add( wx.StaticText( self, -1, "From:" ), 0, wx.EXPAND )
		asizer.Add( self.reply_address, 1, wx.EXPAND )
		asizer.Add( wx.StaticText( self, -1, "CC:" ), 0, wx.EXPAND )
		asizer.Add( self.cc_address, 1, wx.EXPAND )		
		sizer.Add( asizer, 0, wx.EXPAND | wx.LEFT | wx.RIGHT | wx.NORTH, 20 )
		
		# Add the buttons
		self.button_sizer = wx.BoxSizer( wx.HORIZONTAL )
		btn = wx.Button( self, ID_SEND, "&Send" )
		self.btn.Bind( wx.EVT_BUTTON, self.OnSend )
		self.button_sizer.Add( (0,0), 0, 1 )
		self.button_sizer.Add( btn, 1, 0 )
		self.button_sizer.Add( (0,0), 0, 1 )
		btn = wx.Button( self, wx.ID_CANCEL, "&Close" )
		btn.SetDefault()
		self.button_sizer.Add( btn, 1, 0 )
		self.button_sizer.Add( (0,0), 0, 1 )

		self.sizer = wx.BoxSizer( wx.VERTICAL )
		self.sizer.Add( sizer, 1, wx.EXPAND | wx.NORTH | wx.SOUTH | wx.EAST | wx.WEST, 10 )
		self.sizer.Add( self.button_sizer, 0, wx.EXPAND | wx.ALIGN_CENTER | wx.SOUTH, 20 )

		self.SetSizer( self.sizer )
		self.SetAutoLayout( 1 )
		# Windows needs this call
		self.Layout()
		
	def OnSend( self, event ):
		#~ print "OnOk"
		cur = wx.BusyCursor()
		buf = "<send survey_id=\"%s\">" % ( self.survey["id"] )
		if len( self.objects ) < 1: return
		for obj in self.objects.values():
			if obj.object_name == "contact":
				tag = "<contact id=%s />" % saxutils.quoteattr( obj["xid"] )
			elif obj.object_name == "group":
				tag = "<group id=\"%s\" />" % obj["id"]
			else:
				return
			buf = buf + tag
		cdom = buf + "</send>"
		result 	= self.account.execute( "send", DOM=cdom )
		if result:		
			wx.MessageBox( "Your request has been entered and is being processed", "Sending", wx.OK )
			self.Destroy()
		else:
			print "Failed to send"
			# Confirm retry
			wx.MessageBox( "Failed to send, please try again", "Failed to Send", wx.OK )
			
		
	def OnBeginDrag( self, event ):
		list = self.list
		sel = get_selected_in_list( list )
		if len( sel ) < 1: return
		oid  = list.GetItemData( sel[0] )
		#~ print "OID=", oid
		
		data = wx.PyTextDataObject(" ")		
		ds = wx.DropSource( self )
		ds.SetData( data )
		result = ds.DoDragDrop()
		if result == 5:
			# Remove the object
			try:
				self.objects.__delitem__( oid )
				list.DeleteItem( sel[0] )
			except:
				pass
		#~ print self.objects
	
	def AppendObject( self, object ):
		#~ print "AddpenObject, ", object.object_name
		x = self.list.GetItemCount()
		if object.object_name == "contact":
			id = object["xid"]
		elif object.object_name == "group":
			id = object["id"]
		else:
			return
		self.list.InsertStringItem( x, id )
		self.list.SetStringItem( x , 1, object["name"] )
		self.list.SetStringItem( x , 2, object.object_name.capitalize() )
		# Add the object to the list of object to send to
		oid = self.get_new_id()
		self.objects[ oid ] = object
		self.list.SetItemData( x, oid )
		
	def get_new_id( self ):
		self.current_id = self.current_id + 1
		return self.current_id
		
	def resize_columns( self ):
		for i in range(0, self.list.GetColumnCount() -1 ):
			self.list.SetColumnWidth( i, wx.LIST_AUTOSIZE )
